package com.lza.service.impl;

import com.aliyun.oss.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lza.Config.MenuTreeBuilder;
import com.lza.Vo.MenuNodeVO;
import com.lza.Vo.UserInfoVO;
import com.lza.converter.MenuConverter;
import com.lza.entity.*;
import com.lza.enums.UserTypeEnum;
import com.lza.mapper.*;
import com.lza.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lza.shiro.JWTToken;
import com.lza.shiro.JWTUtils;
import com.lza.shiro.MD5Utils;
import com.lza.util.RedisUtil;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author lizhaoao
 * @since 2021-10-12
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    UserRoleMapper userRoleMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    RoleMenuMapper roleMenuMapper;
    @Autowired
    MenuMapper menuMapper;
    @Autowired
    RedisUtil redisUtil;


    @Override
    public User getUserByName(String username) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("username", username);
        User user = this.baseMapper.selectOne(queryWrapper);
        return user;
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        User user = getUserByName(username);
        if (user != null) {
            String salt = user.getSalt();//生成盐
            //秘钥为盐
            String target = MD5Utils.md5Encryption(password, salt);
            token = JWTUtils.sign(username, target);//生成Token
            System.out.println(token);
            JWTToken jwtToken = new JWTToken(token);
            //获取主体对象
            SecurityUtils.getSubject().login(jwtToken);
        }

        return token;
    }




    /**
     * 查询用户角色
     * @param id 用户ID
     * @return
     */

    @Override
    public List<Role> findRolesById(Long id) {
        User dbUser = baseMapper.selectById(id);
        if (dbUser == null) {
            throw new ServiceException("该用户不存在");
        }
        List<Role> roles = new ArrayList<>();
        UserRole t = new UserRole();
        t.setUserId(dbUser.getId());
        QueryWrapper queryWrapper = new QueryWrapper(t);
        List<UserRole> userRoleList = userRoleMapper.selectList(queryWrapper);
        List<Long> rids = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userRoleList)) {
            for (UserRole userRole : userRoleList) {
                rids.add(userRole.getRoleId());
            }
            if (!CollectionUtils.isEmpty(rids)) {
                for (Long rid : rids) {
                    Role role = roleMapper.selectById(rid);
                    if (role != null) {
                        roles.add(role);
                    }
                }
            }
        }
        return roles;
    }


//根据用户角色查找用户菜单
    @Override
    public List<Menu> findMenuByRoles(List<Role> roles) {
        List<Menu> menus=new ArrayList<>();
        if(!CollectionUtils.isEmpty(roles)) {//如果集合不是空
            Set<Long> menuIds=new HashSet<>();//存放用户的菜单id
            List<RoleMenu> roleMenus;
            for(Role role:roles){
                //根据角色id查询权限id
                QueryWrapper<RoleMenu> queryWrapper=new QueryWrapper<>();
                roleMenus=roleMenuMapper.selectList(queryWrapper);//一个角色id可以有多个菜单
                if(!CollectionUtils.isEmpty(roleMenus)){
                    for(RoleMenu roleMenu:roleMenus){
                        menuIds.add(roleMenu.getMenuId());
                    }
                }
            }
            if(!CollectionUtils.isEmpty(menuIds)){
                for(Long menuId:menuIds){
                    Menu menu = menuMapper.selectById(menuId);
                    if(menu!=null){
                        menus.add(menu);
                    }
                }
            }
            return menus;

        }

     return  null;
    }

    @Override//列出所有用户(分页)
    public List<User> findAllUser(Integer pageNum, Integer pageSize) {
        IPage<User> page=new Page(pageNum, pageSize);
        IPage<User> userIPage = baseMapper.selectPage(page, null);
        List<User> records = userIPage.getRecords();
        return records;

    }

    @Override
    public List<Long> roles(Long id) {
        return null;
    }
   //用户所有信息
    @Override
    public UserInfoVO info() {
        //先从redis里面查，如果有直接出结果，否则在shiro里面查，还没有实现修改后要删除的功能
        Object userInfo = redisUtil.get("userInfo");
        UserInfoVO userInfoVO = new UserInfoVO();
        if (userInfo==null) {
            //使用shiro时，如果正常登陆（执行subject.login(token)成功）就能在全局通过SecurityUtils.getSubject().getPrincipal()获取用户信息。
            ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
            userInfoVO.setAvatar(activeUser.getUser().getAvatar());
            userInfoVO.setUsername(activeUser.getUser().getUsername());
            userInfoVO.setUrl(activeUser.getUrls());
            userInfoVO.setNickname(activeUser.getUser().getNickname());
            userInfoVO.setPassword(activeUser.getUser().getPassword());//看密码
            List<String> roleNames = activeUser.getRoles().stream().map(Role::getRoleName).collect(Collectors.toList());
            userInfoVO.setRoles(roleNames);
            userInfoVO.setPerms(activeUser.getPermissions());
            userInfoVO.setIsAdmin(activeUser.getUser().getType()== UserTypeEnum.SYSTEM_ADMIN.getTypeCode());
       /* DepartmentVO dept = departmentService.edit(activeUser.getUser().getDepartmentId());
        if(dept!=null){
            userInfoVO.setDepartment(dept.getName());
        }*/
            redisUtil.set("userInfo",userInfoVO);//放到redis里面
            return userInfoVO;
        }else{
           return (UserInfoVO) userInfo;
        }



    }
    /*
    加载菜单
     */
    @Override
    public List<MenuNodeVO> findMenu() {
        List<Menu> menus=new ArrayList<>();
        List<MenuNodeVO> menuNodeVOS=new ArrayList<>();
        ActiveUser activeUser=(ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if(activeUser.getUser().getType()==UserTypeEnum.SYSTEM_ADMIN.getTypeCode()){
           menus=menuMapper.selectList(null);  //超级管理员
        }
        else if(activeUser.getUser().getType()==UserTypeEnum.SYSTEM_USER.getTypeCode()){
            menus=activeUser.getMenus();//普通用户
        }
        if(!CollectionUtils.isEmpty(menus)){
            menuNodeVOS= MenuConverter.converterToMenuNodeVO(menus);
        }
        return MenuTreeBuilder.build(menuNodeVOS);//构建树形菜单
    }


}
